Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compatibility with Flask 3, WTForms 3, SQLAlchemy 2.0 and others #2467

Merged
merged 6 commits into from
Aug 6, 2024

Conversation

cjmayo
Copy link
Contributor

@cjmayo cjmayo commented Jul 21, 2024

Updated version of #2328.

A problem with monogengine that is skipped here- use flask-mongoengine2?

Obviously there is quite a lot here. What is the best way forward?

@samuelhwilliams
Copy link
Contributor

Yeah I saw the flask-mongoengine issue recently too. Unsure whether we'd want flask-mongoengine2 or flask-mongoengine3. The latter looks a 'bit' more popular, and keeps wtforms support (unsure right now if that's relevant to us - maybe?)

Both do seem to have very little in the way of support/activity, though, so it makes me nervous to switch over to them.

@samuelhwilliams
Copy link
Contributor

I do agree that getting flask-admin into a place where we can officially support the latest version of these key dependencies is a priority. I think Flask v3+ and SQLAlchemy v2+ are big ones.

I think wtforms3 already works - unsure if there are specific issues you've seen that I've maybe missed so far, though?

I think we probably to adjust how we are pinning dependencies for tests, to get a bit more confidence that combinations are working. I have been very vaguely thinking about this in a wip/provisional commit on my fork here: ff22863. But I still have a lot of musings/unanswered questions.

I feel like we maybe next a few sets of tests.in requirements file that pin different combinations of flask/wtforms/sqlalchemy etc.

Maybe on tests-flask2.in file that pins to flask v2, wtforms v2, sqlalchemy v1 and another tests-flask3.in that pins to flask v3, wtforms v3, sqlalchemy v2, etc?

I'm unsure the current tox.ini config is really 'good enough'; maybe separate test requirements files is a bit clearer?

@cjmayo
Copy link
Contributor Author

cjmayo commented Jul 22, 2024

I think wtforms3 already works - unsure if there are specific issues you've seen that I've maybe missed so far, though?

Yes, "Fix translating after WTForms 3 removed form._get_translations" included in this PR is needed.

I think we probably to adjust how we are pinning dependencies for tests, to get a bit more confidence that combinations are working. I have been very vaguely thinking about this in a wip/provisional commit on my fork here: ff22863. But I still have a lot of musings/unanswered questions.

I feel like we maybe next a few sets of tests.in requirements file that pin different combinations of flask/wtforms/sqlalchemy etc.

Maybe on tests-flask2.in file that pins to flask v2, wtforms v2, sqlalchemy v1 and another tests-flask3.in that pins to flask v3, wtforms v3, sqlalchemy v2, etc?

I'm unsure the current tox.ini config is really 'good enough'; maybe separate test requirements files is a bit clearer?

Yes multiple tests.in without the additional dependency selections in tox.ini is basically what I was thinking in https://github.com/pallets-eco/flask-admin/pull/2328/files#diff-ef2cef9f88b4fe09ca3082140e67f5ad34fb65fb6e228f119d3812261ae51449.

I'm probably not the best person to judge how many combinations should be tested - I'm happy with minimum and latest - and kind of think WTForms 2 should be dropped ASAP as the last release was in 2020 (I do realise it isn't realistic for everyone to switch instantly!).

@samuelhwilliams
Copy link
Contributor

I am probably ok with us dropping wtforms2 - and maybe for v2.0.0 makes sense since it's a breaking change anyway? If so we should aim to get that in sooner rather than later?

@cjmayo
Copy link
Contributor Author

cjmayo commented Jul 23, 2024

Fine by me - I've put the WTForms 3 compatibility commit in its own PR #2473 (I guess breaking the commits on this PR down into multiple PRs is going to be the way to get this done).

It would make reduce the number of test combinations.

@samuelhwilliams
Copy link
Contributor

Breaking it down a little bit would probably be helpful, yes 👍

1 PR for each dependency would probably be OK/a good level? Flask3, WTForms3, SQLAlchemy2 - unless you think some other split would be good.

@cjmayo
Copy link
Contributor Author

cjmayo commented Jul 30, 2024

Rebased on master - no code changes left here!

Should the filters go in like this or do they now belong in pyproject.toml?

wtf-peewee 3.0.5 only supports WTForms 3.1.0 4-items tuple return value from iter_choices
coleifer/wtf-peewee@97866c7
There is nothing else in the 3.0.5 release, so pinning 3.0.4 seems reasonable for now?
(or is it potentially a user problem? There was a commit for 3.1.0 compatibility in one of the old PRs)

More to fix for mongoengine...

@samuelhwilliams
Copy link
Contributor

samuelhwilliams commented Jul 30, 2024

I'm undecided about wtf-peewee.

Part of me thinks that we should require wtf-peewee>=3.0.5, which would then implicitly require wtforms>=3.1.0 as you suggest. That would mean people using Flask-Admin for peewee would have to use wtforms 3.1.0+. But I think that's better than limiting users to wtf-peewee==3.0.4 and then implicitly wtforms<3.1.0 - ie forcing them onto older dependencies.

I think neither situation is perfect, but I would tend towards forcing people to be on newer versions of things than forcing them to be on older ones. What do you think?

(flask-)mongoengine is a whole other beast. I am reluctant to remove it altogether, but I don't know what approach we do want to take with supporting a dependency that isn't compatible with the latest versions of flask and probably isn't going to become compatible due to lack of maintenance. I feel like we probably need to cut that loose ... but I'd be very happy to hear an alternative proposal.

@samuelhwilliams
Copy link
Contributor

Should the filters go in like this or do they now belong in pyproject.toml?

I think I'm OK with those filters going in where you've put them. I've just noticed that we no longer need the "Please update your type formatter" filterwarnings - I fixed that issue a while back but clearly missed those.

If you want to strip those filters out in this PR, that'd be great. Otherwise I'll remove them separately after this is in.

@cjmayo
Copy link
Contributor Author

cjmayo commented Jul 31, 2024

But I think that's better than limiting users to wtf-peewee==3.0.4 and then implicitly wtforms<3.1.0 - ie forcing them onto older dependencies.

it would be
wtforms>=2,!=3.10,<3.2

as they restored support in 3.1.1:
https://wtforms.readthedocs.io/en/3.1.x/changes/#version-3-1-1

I think neither situation is perfect, but I would tend towards forcing people to be on newer versions of things than forcing them to be on older ones. What do you think?

For >=3.0.5 we would need #2395 or similar.

(flask-)mongoengine is a whole other beast. I am reluctant to remove it altogether, but I don't know what approach we do want to take with supporting a dependency that isn't compatible with the latest versions of flask and probably isn't going to become compatible due to lack of maintenance. I feel like we probably need to cut that loose ... but I'd be very happy to hear an alternative proposal.

We've already got "Flask<2.3.0" in the mongoengine extra I guess we can add WTForms and/or SQLAlchemy - I'll experiment

flask_admin/tests/sqla/test_form_rules.py:135: in test_rule_inlinefieldlist
    view = CustomModelView(Model1, db.session,
flask_admin/tests/sqla/test_basic.py:33: in __init__
    super(CustomModelView, self).__init__(model, session, name, category,
flask_admin/contrib/sqla/view.py:346: in __init__
    super(ModelView, self).__init__(model, name, category, endpoint, url, static_folder,
flask_admin/model/base.py:834: in __init__
    self._refresh_cache()
flask_admin/model/base.py:968: in _refresh_cache
    self._validate_form_class(self._form_create_rules, self._create_form_class)
flask_admin/model/base.py:1447: in _validate_form_class
    self._show_missing_fields_warning('Fields missing from ruleset: %s' % (','.join(missing_fields)))
flask_admin/model/base.py:1431: in _show_missing_fields_warning
    warnings.warn(text)
E   UserWarning: Fields missing from ruleset: test2,test3,test4,bool_field,date_field,time_field,datetime_field,email_field,enum_field,choice_field,sqla_utils_choice,sqla_utils_enum,sqla_utils_arrow,sqla_utils_uuid,sqla_utils_url,sqla_utils_ip_address,sqla_utils_currency,sqla_utils_color
__________________________________ test_model __________________________________
flask_admin/tests/mongoengine/test_basic.py:117: in test_model
    assert model.test3 == ''
E   AssertionError: assert None == ''
E    +  where None = <Model1: test1large>.test3
Resolved in:
25ac435 ("Update formatter function signatures", 2024-07-15)
@cjmayo cjmayo marked this pull request as ready for review July 31, 2024 19:03
@cjmayo
Copy link
Contributor Author

cjmayo commented Jul 31, 2024

I've put the restrictions on mongoengine and removed the filters. That does pass now so I removed if from draft.
But I don't know what is best for wtf-peewee so I moved it to the end - don't start a review until you decide you want to go with 3.0.4 and I can easily remove it from the end!

@samuelhwilliams
Copy link
Contributor

I think we need to change our use of field.iter_choices() to support both 3-tuples and 4-tuples, then we should be able to unpin wtf-peewee?

In both flask_admin.models.widgets and flask_admin.contrib.sqla.widgets:

for value, label, selected in field.iter_choices()

to

for field_choices in field.iter_choices():
    if len(field_choices) == 3:  # wtforms <3.1, >=3.1.1, <3.2
        value, label, selected = field_choices
    else:
        value, label, selected, _ = field_choices

@cjmayo
Copy link
Contributor Author

cjmayo commented Aug 3, 2024

That worked!

@@ -47,7 +47,9 @@ geoalchemy = [
mongoengine = [ # TODO: seems out-of-date/unmaintained; replace or deprecate?
"Flask-Admin[sqlalchemy]",
"flask-mongoengine<1",
"Flask<2.3.0", # flask-mongoengine tries to access `flask.json`
"Flask<2.3.0", # flask-mongoengine tries to access `flask.json`,
"sqlalchemy>=1.4,<2",
Copy link
Contributor

@samuelhwilliams samuelhwilliams Aug 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to repeat the >=1.4 here, as we get this from the sqlalchemy optional group already. Ie this could maybe just be sqlalchemy<2

However it's all a bit moot, as I have a PR up to remove support for mongoengine altogether.

@samuelhwilliams samuelhwilliams merged commit b8a2e5d into pallets-eco:master Aug 6, 2024
12 checks passed
@cjmayo cjmayo deleted the new_version3 branch August 7, 2024 18:36
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 22, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants